//
//  ZYUIExtension.swift
//  ZYUICommon
//
//  Created by Yi Zhou on 2025/1/4.
//  
//

import UIKit
import Kingfisher

// MARK: - UIView
@MainActor
public extension UIView {
    
    /// 获取视图的X坐标
    var x: CGFloat {
        get {
            return self.frame.origin.x;
        }
        
        set {
            var frames = self.frame;
            frames.origin.x = CGFloat(newValue);
            self.frame = frames;
        }
    }
    
    /// 获取视图的Y坐标
    var y: CGFloat {
        get {
            return self.frame.origin.y;
        }
        
        set {
            var frames = self.frame;
            frames.origin.y = CGFloat(newValue);
            self.frame = frames;
        }
    }
    
    /// 获取origin
    var origin: CGPoint {
        get {
            return self.frame.origin
        }
        
        set {
            self.frame.origin = newValue
        }
    }
    
    /// 获取size
    var size: CGSize {
        get {
            return self.frame.size
        }
        
        set {
            self.frame.size = newValue
        }
    }
    
    /// 获取视图的宽
    var width: CGFloat {
        get {
            return self.frame.size.width;
        }
        
        set {
            var frames = self.frame;
            frames.size.width = CGFloat(newValue);
            self.frame = frames;
        }
    }
    
    /// 获取视图的高
    var height: CGFloat {
        get {
            return self.frame.size.height;
        }
        
        set {
            var frames = self.frame;
            frames.size.height = CGFloat(newValue);
            self.frame = frames;
        }
    }
    
    /// 获取最大的X坐标
    var maxX: CGFloat {
        get {
            return self.x + self.width;
        }
        
        set {
            var frames = self.frame;
            frames.origin.x = CGFloat(newValue - self.width);
            self.frame = frames;
        }
    }
    
    /// 获取最大的Y坐标
    var maxY: CGFloat {
        get {
            return self.y + self.height;
        }
        
        set {
            var frames = self.frame;
            frames.origin.y = CGFloat(newValue - self.height);
            self.frame = frames;
        }
    }
    
    /// 中心点X坐标
    var centerX: CGFloat {
        get {
            return self.center.x;
        }
        set {
            self.center = CGPoint(x: CGFloat(newValue), y: self.center.y);
        }
    }
    
    /// 中心点Y坐标
    var centerY: CGFloat {
        get {
            return self.center.y;
        }
        set {
            self.center = CGPoint(x: self.center.x, y: CGFloat(newValue));
        }
    }
    
    /// frame
    /// - Parameter frame: frame description
    /// - Returns: description
    @discardableResult
    func zyFrame(_ frame: CGRect) -> Self {
        self.frame = frame
        return self
    }
    
    /// 背景色
    /// - Parameter color: color description
    /// - Returns: description
    @discardableResult
    func zyBackgroundColor(_ color: UIColor) -> Self {
        self.backgroundColor = color
        return self
    }
    
    /// 隐藏/显示
    /// - Parameter isHidden: isHidden description
    /// - Returns: description
    @discardableResult
    func zyHidden(_ isHidden: Bool) -> Self {
        self.isHidden = isHidden
        return self
    }
    
    /// 显示模式
    /// - Parameter mode: mode description
    /// - Returns: description
    @discardableResult
    func zyContentMode(_ mode: UIView.ContentMode) -> Self {
        self.contentMode = mode
        return self
    }
    
    /// 设置所有圆角
    /// - Parameter value: value description
    /// - Returns: description
    @discardableResult
    func zyAllCornerRadius(_ value: CGFloat) -> Self {
        self.layer.cornerRadius = value
        self.clipsToBounds = true
        return self
    }
    
    /// 设置单个圆角
    /// - Parameters:
    ///   - rect: rect description
    ///   - radius: radius description
    ///   - corner: corner description
    /// - Returns: description
    @discardableResult
    func zySeparateCornerRadius(_ rect: CGRect, _ radius: CGFloat, _ corner: UIRectCorner) -> Self {
        let maskPath = UIBezierPath(
            roundedRect: rect,
            byRoundingCorners: corner,
            cornerRadii: CGSize(width: radius, height: radius))
        let shape = CAShapeLayer()
        shape.path = maskPath.cgPath
        self.layer.mask = shape
        return self
    }
    
    /// 设置边框
    /// - Parameters:
    ///   - color: color description
    ///   - value: value description
    /// - Returns: description
    @discardableResult
    func zyBorder(_ color: UIColor, _ value: CGFloat) -> Self {
        self.layer.borderColor = color.cgColor
        self.layer.borderWidth = value
        self.clipsToBounds = true
        return self
    }
    
    /// 禁用/非禁用
    /// - Parameter isEnable: isEnable description
    /// - Returns: description
    @discardableResult
    func zyUserInteraction(_ isEnable: Bool) -> Self {
        self.isUserInteractionEnabled = isEnable
        return self
    }
    
    /// 添加点击手势
    /// - Parameter closure: 手势事件响应回调
    /// - Returns: description
    @discardableResult
    func zyAddTapGesture(_ closure: @escaping () -> Void) -> Self {
        let wrapper = ClosureWrapper(closure: closure)
        objc_setAssociatedObject(self, String(format: "%@", UUID().uuidString), wrapper, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        let ges = UITapGestureRecognizer(target: wrapper, action: #selector(ClosureWrapper.invokeClosure))
        ges.numberOfTapsRequired = 1
        ges.numberOfTouchesRequired = 1
        self.addGestureRecognizer(ges)
        return self
    }
    
    /// 移除所有子View
    /// - Returns: description
    @discardableResult
    func zyRemoveAllSubviews() -> Self {
        self.subviews.forEach { subview in
            subview.removeFromSuperview()
        }
        return self
    }
    
    /// 一次性添加子view
    /// - Parameter subviews: subviews description
    /// - Returns: description
    @discardableResult
    func zyAddChild(_ subviews: [UIView]) -> Self {
        subviews.forEach { subview in
            self.addSubview(subview)
        }
        return self
    }
    
    /// 添加渐变色背景
    /// - Parameters:
    ///   - colors: 渐变色
    ///   - startPoint: 起点
    ///   - endPoint: 终点
    @discardableResult
    func zyGridentBackgroundColor(_ colors: [UIColor], _ startPoint: CGPoint = CGPoint(x: 0.5, y: 0), _ endPoint: CGPoint = CGPoint(x: 0.5, y: 1)) -> Self {
        var cgColors = [CGColor]()
        for color in colors {
            cgColors.append(color.cgColor)
        }
        let bgLayer = CAGradientLayer()
        bgLayer.colors = cgColors
        bgLayer.locations = [0, 1]
        bgLayer.frame = self.bounds
        bgLayer.startPoint = startPoint
        bgLayer.endPoint = endPoint
        self.layer.addSublayer(bgLayer)
        return self
    }
    
    private class ClosureWrapper: NSObject {
        var closure: (() -> Void)?
        init(closure: @escaping () -> Void) {
            self.closure = closure
        }
        @objc func invokeClosure() {
            closure?()
        }
    }
}

// MARK: - UILabel
@MainActor
public extension UILabel {
    
    /// 字体
    /// - Parameters:
    ///   - font: font description
    ///   - weight: weight description
    /// - Returns: description
    @discardableResult
    func zyFont(_ font: CGFloat, _ weight: UIFont.Weight = .regular) -> Self {
        self.font = UIFont.systemFont(ofSize: font, weight: weight)
        return self
    }
    
    /// 颜色
    /// - Parameter color: color description
    /// - Returns: description
    @discardableResult
    func zyTextColor(_ color: UIColor) -> Self {
        self.textColor = color
        return self
    }
    
    /// 对齐方式
    /// - Parameter alignment: alignment description
    /// - Returns: description
    @discardableResult
    func zyTextAlignment(_ alignment: NSTextAlignment) -> Self {
        self.textAlignment = alignment
        return self
    }
    
    /// 文本
    /// - Parameter text: text description
    /// - Returns: description
    @discardableResult
    func zyText(_ text: String) -> Self {
        self.text = text
        return self
    }
    
    /// 行数
    /// - Parameter numLine: numLine description
    /// - Returns: description
    @discardableResult
    func zyNumberOfLines(_ numLine: Int) -> Self {
        self.numberOfLines = numLine
        return self
    }
}

// MARK: - UIButton
@MainActor
public extension UIButton {
    
    /// 字体
    /// - Parameters:
    ///   - font: font description
    ///   - weight: weight description
    /// - Returns: description
    @discardableResult
    func zyFont(_ font: CGFloat, _ weight: UIFont.Weight = .regular) -> Self {
        self.titleLabel?.font = UIFont.systemFont(ofSize: font, weight: weight)
        return self
    }
    
    /// 常规态文字
    /// - Parameter title: title description
    /// - Returns: description
    @discardableResult
    func zyNormalText(_ title: String) -> Self {
        self.setTitle(title, for: .normal)
        return self
    }
    
    /// 选中态文字
    /// - Parameter title: title description
    /// - Returns: description
    @discardableResult
    func zySelectedText(_ title: String) -> Self {
        self.setTitle(title, for: .selected)
        return self
    }
    
    /// 禁用态文字
    /// - Parameter title: title description
    /// - Returns: description
    @discardableResult
    func zyDisabledText(_ title: String) -> Self {
        self.setTitle(title, for: .disabled)
        return self
    }
    
    /// 常规态文字颜色
    /// - Parameter color: color description
    /// - Returns: description
    @discardableResult
    func zyNormalTextColor(_ color: UIColor) -> Self {
        self.setTitleColor(color, for: .normal)
        return self
    }
    
    /// 选中态文字颜色
    /// - Parameter color: color description
    /// - Returns: description
    @discardableResult
    func zySelectedTextColor(_ color: UIColor) -> Self {
        self.setTitleColor(color, for: .selected)
        return self
    }
    
    /// 禁用态文字颜色
    /// - Parameter color: color description
    /// - Returns: description
    @discardableResult
    func zyDisabledTextColor(_ color: UIColor) -> Self {
        self.setTitleColor(color, for: .disabled)
        return self
    }
    
    /// 常规态图片
    /// - Parameter image: image description
    /// - Returns: description
    @discardableResult
    func zyNormalImage(_ image: UIImage?) -> Self {
        self.setImage(image, for: .normal)
        return self
    }
    
    /// 选中态图片
    /// - Parameter image: image description
    /// - Returns: description
    @discardableResult
    func zySelectedImage(_ image: UIImage?) -> Self {
        self.setImage(image, for: .selected)
        return self
    }
    
    /// 禁用态图片
    /// - Parameter image: image description
    /// - Returns: description
    @discardableResult
    func zyDisabledImage(_ image: UIImage?) -> Self {
        self.setImage(image, for: .disabled)
        return self
    }
    
    /// 常规背景色
    /// - Parameters:
    ///   - color: color description
    ///   - size: size description
    /// - Returns: description
    @discardableResult
    func zyNormalBackgroundColor(_ color: UIColor, _ size: CGSize) -> Self {
        self.setBackgroundImage(ZYUtil.imageWithColor(color, size), for: .normal)
        return self
    }
    
    /// 选中态背景色
    /// - Parameters:
    ///   - color: color description
    ///   - size: size description
    /// - Returns: description
    @discardableResult
    func zySelectBackgroundColor(_ color: UIColor, _ size: CGSize) -> Self {
        self.setBackgroundImage(ZYUtil.imageWithColor(color, size), for: .selected)
        return self
    }
    
    /// 禁用态背景色
    /// - Parameters:
    ///   - color: color description
    ///   - size: size description
    /// - Returns: description
    @discardableResult
    func zyDisabledBackgroundColor(_ color: UIColor, _ size: CGSize) -> Self {
        self.setBackgroundImage(ZYUtil.imageWithColor(color, size), for: .disabled)
        return self
    }
    
    /// 添加响应事件
    /// - Parameters:
    ///   - controlEvents: controlEvents description
    ///   - closure: closure description
    /// - Returns: description
    @discardableResult
    func zyAddTarget(_ controlEvents: UIControl.Event = .touchUpInside, closure: @escaping () -> Void) -> Self {
        let wrapper = ClosureWrapper(closure: closure)
        objc_setAssociatedObject(self, String(format: "%@", UUID().uuidString), wrapper, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        addTarget(wrapper, action: #selector(ClosureWrapper.invokeClosure), for: controlEvents)
        return self
    }
    
    /// 防止重复点击
    /// - Parameter interval: 间隔时长（秒）
    @discardableResult
    func zyRepeatedClickControls(_ interval: Double) -> Self {
        self.isEnabled = false
        DispatchQueue.main.asyncAfter(deadline:.now() + interval) { [weak self] in
            self?.isEnabled = true
        }
        return self
    }
    
    private class ClosureWrapper: NSObject {
        var closure: (() -> Void)?
        init(closure: @escaping () -> Void) {
            self.closure = closure
        }
        @objc func invokeClosure() {
            closure?()
        }
    }
    
}

//MARK: - UIImage
@MainActor
public extension UIImage {
    
    /// 压缩图片大小
    /// - Parameters:
    ///   - original: original description
    ///   - targetSize: targetSize description
    /// - Returns: description
    func compressTo(_ targetSize: CGSize) -> UIImage? {
        guard self.size.height * self.size.width > 0 else { return nil }
        guard self.size != targetSize, self.size.width >= targetSize.width, self.size.height >= targetSize.height else { return self }
        
        return autoreleasepool {
            var newImage: UIImage?
            let widthScale = targetSize.width / self.size.width
            let heightScale = targetSize.height / self.size.height
            let scale = max(widthScale, heightScale)
            let fixTargetSize = CGSize(width: self.size.width * scale, height: self.size.height * scale)
            
            let targetRect = CGRect(origin: CGPoint.zero, size: fixTargetSize)
            UIGraphicsBeginImageContextWithOptions(fixTargetSize, false, 1)
            self.draw(in: targetRect)
            newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
    
            return newImage
        }
    }
    
    /// 旋转图片
    /// - Parameters:
    ///   - degrees: 旋转角度
    /// - Returns: 旋转完毕的图片
    func rotated(by degrees: CGFloat) -> UIImage? {
        let radians = degrees * .pi / 180.0
        let rotatedSize = CGRect(origin: .zero, size: size)
            .applying(CGAffineTransform(rotationAngle: radians))
            .integral.size
        
        UIGraphicsBeginImageContextWithOptions(rotatedSize, false, scale)
        defer { UIGraphicsEndImageContext() }
        
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        
        context.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2)
        context.rotate(by: radians)
        context.translateBy(x: -size.width / 2, y: -size.height / 2)
        
        draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
    
    /// 图片圆角
    /// - Parameter cornerRadius: cornerRadius description
    /// - Returns: description
    func roundedImage(_ cornerRadius: CGFloat) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        let rect = CGRect(origin: .zero, size: size)
        UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).addClip()
        draw(in: rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

//MARK: - UIImageView
@MainActor
public extension UIImageView {
    
    /// 设置网络图片
    /// - Parameters:
    ///   - url: url description
    ///   - placeholder: placeholder description
    func setImageWith(_ url: String, _ placeholder: UIImage = UIImage()) {
        self.kf.setImage(with: URL(string: url),
                         placeholder: placeholder,
                         options: [.cacheMemoryOnly,.transition(.fade(0.2))])
    }
    
}

//MARK: - 类名
public extension NSObject {
    static var className: String {
        return NSStringFromClass(self)
    }
}
